﻿
Imports System.Reflection

Public Class fieldvalue(Of T)
    Private ReadOnly _valid As Boolean = False
    Private ReadOnly v As T = Nothing

    Public Sub New(ByVal t As Type, ByVal bindingFlags As BindingFlags, ByVal obj As Object, ByVal name As String)
        If Not t Is Nothing AndAlso Not isemptystring(name) Then
            Dim fi As FieldInfo = Nothing
            Try
                fi = t.GetField(name, bindingFlags)
            Catch ex As Exception
                raiseError(errorHandle.errorType.warning,
                           "cannot find field ", name, " in type ", t, ", ex ", ex.Message)
            End Try

            If Not fi Is Nothing Then
                Dim o As Object = Nothing
                Try
                    o = fi.GetValue(obj)
                Catch ex As Exception
                    raiseError(errorHandle.errorType.warning,
                               "cannot get value from field ", name, " in type ", t, ", ex ", ex.Message)
                End Try

                If convertor.cast(Of T)(o, v) Then
                    _valid = True
                Else
                    raiseError(errorHandle.errorType.warning,
                               "cannot convert field ", name, " value in type ", t, " to ", GetType(T).Name())
                End If
            End If
        End If
    End Sub

    Public Sub New(ByVal t As Type, ByVal bindingFlags As BindingFlags, ByVal name As String)
        Me.New(t, bindingFlags, Nothing, name)
    End Sub

    Public Sub New(ByVal t As Type, ByVal name As String)
        Me.New(t, BindingFlags.Static Or BindingFlags.Public, Nothing, name)
    End Sub

    Public Sub New(ByVal t As Type, ByVal obj As Object, ByVal name As String)
        Me.New(t, BindingFlags.Static Or BindingFlags.Instance Or BindingFlags.Public, obj, name)
    End Sub

    Public Sub New(ByVal obj As Object, ByVal name As String)
        Me.New(obj.GetType(), obj, name)
    End Sub

    Public Sub New(ByVal obj As Object, ByVal bindingFlags As BindingFlags, ByVal name As String)
        Me.New(obj.GetType(), bindingFlags, obj, name)
    End Sub

    Public Sub New(ByVal bindingFlags As BindingFlags, ByVal obj As Object, ByVal name As String)
        Me.New(obj, bindingFlags, name)
    End Sub

    Public Function valid() As Boolean
        Return _valid
    End Function

    Public Shared Operator +(ByVal this As fieldvalue(Of T)) As T
        If this Is Nothing OrElse Not this.valid() Then
            Return Nothing
        Else
            Return this.v
        End If
    End Operator
End Class
